import { BaseLayer } from './BaseLayer';
import { DataAdapterOptions, BatchImportOptions, LoadProgress } from '../types';
import { VectorTile as OlVectorTileLayer } from 'ol/layer';
import { VectorTile as VectorTileSource } from 'ol/source';
import MVT from 'ol/format/MVT';
import { VectorTileOptions } from '../types';
import { Feature } from 'ol';
import { Geometry } from 'ol/geom';
import { StyleCache } from '../utils/StyleCache';

/**
 * 矢量瓦片图层，用于高性能渲染大规模矢量数据
 */
export class VectorTileLayer extends BaseLayer {
  protected options: VectorTileOptions;
  private source: VectorTileSource | null = null;
  private layerStyles: { [layerName: string]: any } = {};
  
  /**
   * 构造函数
   * @param options 图层配置
   */
  constructor(options: VectorTileOptions) {
    super(options);
    this.options = options;
    this.layerStyles = options.layerStyles || {};
  }
  
  /**
   * 创建图层
   */
  protected createLayer(): void {
    // 创建MVT格式解析器
    const format = new MVT({
      idProperty: 'id'
    });
    
    // 创建矢量瓦片数据源
    this.source = new VectorTileSource({
      url: this.options.url || '',
      format: format,
      tileGrid: this.options.tileGrid ? this.createTileGrid() : undefined
    });
    
    // 创建矢量瓦图层
    this.layer = new OlVectorTileLayer({
      source: this.source,
      style: this.getVectorTileStyle.bind(this)
    });
  }
  
  /**
   * 创建瓦片网格
   * @returns 瓦片网格配置
   */
  private createTileGrid(): any {
    if (!this.options.tileGrid) return undefined;
    
    const { extent, resolutions, tileSize } = this.options.tileGrid;
    return {
      extent,
      resolutions,
      tileSize
    };
  }
  
  /**
   * 获取矢量瓦片样式函数
   * @param feature 瓦片特征
   * @param resolution 分辨率
   * @returns 样式或样式数组
   */
  private getVectorTileStyle(feature: any, resolution: number): any {
    const layerName = feature.get('layer') || 'default';
    
    // 根据图层名获取对应的样式配置
    const styleConfig = this.layerStyles[layerName];
    
    if (!styleConfig) {
      return this.getDefaultStyle(feature, resolution);
    }
    
    // 处理样式函数
    if (typeof styleConfig === 'function') {
      return styleConfig(feature, resolution);
    }
    
    return this.createStyleFromConfig(styleConfig, feature, resolution);
  }
  
  /**
   * 根据配置创建样式
   * @param config 样式配置
   * @param feature 特征
   * @param resolution 分辨率
   * @returns OpenLayers样式
   */
  private createStyleFromConfig(config: any, feature: any, resolution: number): any {
    const styleCache = StyleCache.getInstance();
    
    // 处理动态属性（如基于特征属性的值）
    const processedConfig = this.processDynamicConfig(config, feature);
    
    // 使用样式缓存
    return styleCache.getStyle(processedConfig);
  }
  
  /**
   * 处理动态样式配置
   * @param config 原始配置
   * @param feature 特征
   * @returns 处理后的配置
   */
  private processDynamicConfig(config: any, feature: any): any {
    if (typeof config === 'object' && config !== null) {
      const processed: any = {};
      
      Object.keys(config).forEach(key => {
        const value = config[key];
        
        // 处理函数值
        if (typeof value === 'function') {
          processed[key] = value(feature);
        } 
        // 递归处理嵌套对象
        else if (typeof value === 'object' && value !== null) {
          processed[key] = this.processDynamicConfig(value, feature);
        } 
        // 直接复制原始值
        else {
          processed[key] = value;
        }
      });
      
      return processed;
    }
    
    return config;
  }
  
  /**
   * 获取默认样式
   * @param feature 特征
   * @param resolution 分辨率
   * @returns 默认样式
   */
  private getDefaultStyle(feature: any, resolution: number): any {
    const geometryType = feature.getGeometry()?.getType();
    
    switch (geometryType) {
      case 'Point':
      case 'MultiPoint':
        return this.getDefaultPointStyle();
      case 'LineString':
      case 'MultiLineString':
        return this.getDefaultLineStyle();
      case 'Polygon':
      case 'MultiPolygon':
        return this.getDefaultPolygonStyle();
      default:
        return [];
    }
  }
  
  /**
   * 获取默认点样式
   * @returns 点样式配置
   */
  private getDefaultPointStyle(): any {
    return {
      image: {
        type: 'circle',
        radius: 5,
        fill: { color: 'rgba(255, 0, 0, 0.8)' },
        stroke: { color: '#ffffff', width: 1 }
      }
    };
  }
  
  /**
   * 获取默认线样式
   * @returns 线样式配置
   */
  private getDefaultLineStyle(): any {
    return {
      stroke: {
        color: '#0000ff',
        width: 2
      }
    };
  }
  
  /**
   * 获取默认面样式
   * @returns 面样式配置
   */
  private getDefaultPolygonStyle(): any {
    return {
      fill: {
        color: 'rgba(0, 255, 0, 0.3)'
      },
      stroke: {
        color: '#009900',
        width: 1
      }
    };
  }
  
  /**
   * 更新图层样式
   * @param layerName 图层名
   * @param style 样式配置或函数
   */
  updateLayerStyle(layerName: string, style: any): void {
    this.layerStyles[layerName] = style;
    
    // 触发重绘
    if (this.layer) {
      this.layer.changed();
    }
  }
  
  /**
   * 更新多个图层的样式
   * @param styles 样式配置对象，键为图层名
   */
  updateLayerStyles(styles: { [layerName: string]: any }): void {
    this.layerStyles = { ...this.layerStyles, ...styles };
    
    // 触发重绘
    if (this.layer) {
      this.layer.changed();
    }
  }
  
  /**
   * 清除图层缓存，强制重新加载瓦片
   */
  clearTileCache(): void {
    if (this.source) {
      this.source.clear();
    }
  }
  
  /**
   * 获取图层的统计信息
   * @returns 统计信息对象
   */
  getStatistics(): { [key: string]: any } {
    return {
      type: 'VectorTileLayer',
      url: this.options.url,
      layers: Object.keys(this.layerStyles),
      visibilityRange: this.options.visibilityRange,
      webGLEnabled: this.options.useWebGL
    };
  }
}